		TITLE	EXEPACK - Copyright (c) SLR Systems 1994

		INCLUDE	MACROS
		INCLUDE	SEGMENTS
		INCLUDE	SEGMSYMS

		PUBLIC	OS2_EXEPACK,OS2PACK_INIT,OS2_EXEPACK_FLUSH


		.DATA

		EXTERNDEF	EXETABLE:DWORD,EXEPACK_LIMIT:DWORD,PACK_REPT_COUNT:DWORD,LAST_SEG_OS2_NUMBER:DWORD
		EXTERNDEF	NEW_REPT_ADDR:DWORD,PACK_SO_FAR:DWORD,TARG_ADDR:DWORD,HIGH_WATER:DWORD,OLD_HIGH_WATER:DWORD
		EXTERNDEF	EXEPACK_SEGMENT_START:DWORD,FINAL_HIGH_WATER:DWORD,SEGMENT_TABLE:DWORD

		EXTERNDEF	RESIDENT_STRUCTURE:SEQ_STRUCT

		EXTERNDEF	EXEPACK_ROUTINE:DWORD


		.CODE	PASS2_TEXT

		EXTERNDEF	CONVERT_SUBBX_TO_EAX:PROC,RELEASE_BLOCK:PROC,GET_NEXT_BUFFER:PROC,MOVE_EAX_TO_EDX_FINAL:PROC
		EXTERNDEF	INIT_INOUTBUF:PROC,STORE_EAXECX_EDXEBX_RANDOM:PROC,REAL_EXEPACK_FLUSH:PROC,FLUSH_EAX_TO_FINAL:PROC
		EXTERNDEF	MOVE_EAX_TO_FINAL_HIGH_WATER:PROC,RELEASE_EXETABLE_5:PROC


COMMENT ~

	MUST HAVE AT LEAST THIS MANY DUPLICATES TO TRY IT...

FOR	SEGMENTED

		ANY	INITIAL	MID
BYTES		10	  6	 2
WORDS		 5	  3	 2
DWORDS		 3	  2	 2


FOR	REAL

		ANY	INITIAL	MID
BYTES		 6	  4	 2
WORDS		 4	  2	 2
DWORDS		 2	  2	 2


~

OS2_EXEPACK	PROC
		;
		;SCAN, STARTING AT PC=0 GOING THROUGH HIGH_WATER, LOOKING
		;FOR SIMPLE PATTERNS THAT CAN BE COMPRESSED
		;
		;
		;LOAD 2048 BYTES AT A TIME INTO BUF, FOR CONTINUOUS SERVICE.
		;
		;START AT BEGINNING OF SEGMENT
		;
		CALL	OS2_E1

		GETT	AL,EXEPACK_USING_NEW

		OR	AL,AL
		JNZ	L9$
		;
		;SEE IF WE HAVE SAVED ENOUGH BYTES (AT LEAST 8 FOR NOW...)
		;
		MOV	EAX,HIGH_WATER
		MOV	ECX,TARG_ADDR

		SUB	EAX,ECX
		JC	L9$

		CMP	EAX,76			;8 BYTES SMALLER YET (+12)?
		JBE	L9$
		;
		;OK, WE ARE GOING TO KEEP NEW STUFF, FLUSH ANY SO FAR TO FINAL
		;
		CALL	FLUSH_RESIDENT	;TO FINAL, RESET NEW_ADDR, MARK ITER,
L9$:
		RET


OS2_E1		LABEL	PROC

		MOV	EAX,EXEPACK_ROUTINE

		PUSH	EAX
		JMP	INIT_INOUTBUF

OS2_EXEPACK	ENDP


OS2PACK_INIT	PROC
		;
		;SI POINTS TO FIRST VALID POSITION
		;
		XOR	EDX,EDX
		JMP	PMAIN_LOOP_CHECK

PMAIN_LOOP:
		MOV	AL,[ESI]
		MOV	CL,[ESI+4]

		CMP	AL,CL
		JNZ	MAIN_NEXT

		MOV	AH,[ESI+1]
		MOV	CH,[ESI+5]

		CMP	AH,CH
		JZ	PMAYBE
MAIN_NEXT:
PMAYBE_RET::
		INC	ESI
		INC	EDX		;COUNT BYTES THIS GROUP
PMLC_1:
		CMP	EBX,ESI
		JA	PMAIN_LOOP
PMAIN_FILL:
		CALL	PFLUSH_GET_NEXT_BUFFER	;COPY, THEN GET NEW
PMAIN_LOOP_CHECK::
		CMP	EXEPACK_LIMIT,EBX
		JNZ	PMLC_1

		JMP	PEXEPACK_FINISH

OS2PACK_INIT	ENDP


PMAYBE:
		MOV	CL,[ESI+2]

		MOV	CH,[ESI+3]

		CMP	CX,AX
		JZ	PB_OR_W
		;
		;WELL, ONLY CHANCE IS 3 DWORDS
		;
		MOV	AL,[ESI+6]

		MOV	AH,[ESI+7]

		CMP	CX,AX
		JNZ	PMAYBE_RET
		;
		; GOT 2, HOW ABOUT 3???
		;
		MOV	EAX,[ESI]
		MOV	ECX,[ESI+8]

		CMP	EAX,ECX
		JZ	PYES_DWORDS

		TEST	EDX,EDX
		JNZ	PMAYBE_RET

		CMP	PACK_SO_FAR,EDX
		JZ	PYES_DWORDS

		JMP	PMAYBE_RET

PB_OR_W:
		;
		;GOT 3 WORDS MATCHING
		;
		CMP	AL,AH		;BYTES?
		JZ	PYES_BYTES
		;
		;NEED TWO MORE MATCH FOR WORDS
		;
		CMP	4[ESI],AX
		JNZ	PWORDS_3_ENUF?

		CMP	6[ESI],AX
		JZ	PYES_WORDS
PWORDS_3_ENUF?:
		TEST	EDX,EDX
		JNZ	PMAYBE_RET

		CMP	PACK_SO_FAR,EDX
PMAYBE_RET1:
		JNZ	PMAYBE_RET
PYES_WORDS:
		CALL	PSTORE_BYTES_DX_1	;DX BYTES, 1 ITERATION

		MOV	AX,[ESI]
		MOV	EDI,ESI
PYES_WORD:
		;
		;WE AT LEAST HAVE 3 WORDS, SEE WHAT ELSE WE CAN COME UP WITH.
		;
		MOV	ECX,EBX
		XOR	EDX,EDX

		SUB	ECX,EDI			;MAX WE CAN SCAN IN ONE SHOT

		SHR	ECX,1
		JZ	PANOTHER_WORD

		MOV	EDX,ECX			;# WE SCANNED...

		REPE	SCASW

		JZ	PANOTHER_WORD

		SUB	EDX,ECX			;# FOUND
		LEA	ESI,[EDI-2]

		DEC	EDX
		CALL	PSTORE_WORDTYPE		;SPECIAL CASES HANDLED...

		XOR	EDX,EDX
		JMP	PMAIN_LOOP_CHECK

PANOTHER_WORD:
		;
		;STILL CRUISING, GET ANOTHER BUFFER PLEASE
		;
		ADD	PACK_SO_FAR,EDX
		MOV	ESI,EDI

		CALL	GET_NEXT_BUFFER

		MOV	EDI,ESI
		JNC	PYES_WORD

		XOR	EDX,EDX
		CALL	PSTORE_WORDTYPE

		XOR	EDX,EDX
		JMP	PEXEPACK_FINISH

PYES_BYTES:
		;
		;GOT 6, USUALLY NEED 10
		;
		CMP	4[ESI],AX
		JNZ	PBYTES_6_ENUF?

		CMP	6[ESI],AX
		JZ	PYES_BYTE
PBYTES_6_ENUF?:
		TEST	EDX,EDX
		JNZ	PMAYBE_RET

		CMP	PACK_SO_FAR,EDX
		JNZ	PMAYBE_RET
PYES_BYTE:
		CALL	PSTORE_BYTES_DX_1	;STORE PREVIOUS COUNT

		MOV	AL,[ESI]
		MOV	EDI,ESI
		;
		;WE AT LEAST HAVE 6 BYTES, SEE WHAT ELSE WE CAN COME UP WITH.
		;WE ARE SCANNING FOR BYTES...
		;
PYB_1:
		MOV	ECX,EBX

		SUB	ECX,EDI			;MAX WE CAN SCAN IN ONE SHOT
		JZ	PANOTHER_BYTE

		MOV	EDX,ECX			;# WE SCANNED...

		REPE	SCASB

		JZ	PANOTHER_BYTE

		SUB	EDX,ECX			;# FOUND
		LEA	ESI,[EDI-1]

		DEC	EDX
		CALL	PSTORE_BYTETYPE		;SPECIAL CASES HANDLED...

		XOR	EDX,EDX
		JMP	PMAIN_LOOP_CHECK

PYES_DWORDS:
		CALL	PSTORE_BYTES_DX_1

		MOV	EAX,[ESI]
		MOV	EDI,ESI

		;WE ARE SCANNING FOR DWORDS...
PYD_1:
		MOV	ECX,EBX
		XOR	EDX,EDX

		SUB	ECX,ESI			;MAX WE CAN SCAN IN ONE SHOT

		SHR	ECX,2
		JZ	PANOTHER_DWORD

		MOV	EDX,ECX			;# WE SCANNED...

		REPE	SCASD

		JZ	PANOTHER_DWORD

		SUB	EDX,ECX			;# FOUND
		LEA	ESI,[EDI-4]

		DEC	EDX
		CALL	PSTORE_DWORDTYPE	;SPECIAL CASES HANDLED...

		XOR	EDX,EDX
		JMP	PMAIN_LOOP_CHECK

PANOTHER_BYTE:
		;
		;STILL CRUISING, GET ANOTHER BUFFER PLEASE
		;
		;BX DUPLICATE BYTES LIKE AL HAVE BEEN STORED
		;
		ADD	PACK_SO_FAR,EDX
		MOV	ESI,EDI

		CALL	GET_NEXT_BUFFER

		MOV	EDI,ESI
		JNC	PYB_1

		XOR	EDX,EDX
		CALL	PSTORE_BYTETYPE

		XOR	EDX,EDX
		JMP	PEXEPACK_FINISH

PANOTHER_DWORD:
		ADD	PACK_SO_FAR,EDX
		MOV	ESI,EDI

		CALL	GET_NEXT_BUFFER

		MOV	EDI,ESI
		JNC	PYD_1

		XOR	EDX,EDX
		CALL	PSTORE_DWORDTYPE

		XOR	EDX,EDX
		JMP	PEXEPACK_FINISH


PEXEPACK_FINISH	PROC
		;
		;THIS IS FINAL FLUSHING...
		;
		;
		;FLUSH PARTIAL BLOCK
		;
;		CALL	PSTORE_BYTES_DX_1
		;
		;FLUSH DANGLING PIECE
		;
		MOV	EDX,EXEPACK_LIMIT

		SUB	EDX,ESI

		ADD	ESI,EDX
		CALL	PSTORE_BYTES_DX_1
		;
		;NOW COMPARE HIGH_WATER WITH NEW_REPT_ADDR
		;
		MOV	EAX,OLD_HIGH_WATER
		GETT	CL,EXEPACK_USING_NEW

		TEST	EAX,EAX
		JZ	RETTT

		OR	CL,CL
		JNZ	FINI_DONE

		SUB	EAX,NEW_REPT_ADDR
		JC	USE_OLD

		CMP	EAX,76			;8 BYTES SMALLER YET (+12)?
		JB	USE_OLD
		;
		;OK, WE ARE GOING TO KEEP NEW STUFF, FLUSH ANY SO FAR TO FINAL
		;
		CALL	FLUSH_RESIDENT
FINI_DONE:
		MOV	EDX,FINAL_HIGH_WATER
		MOV	EAX,EXEPACK_SEGMENT_START

		SUB	EDX,EAX
FINI_DONE1:
		MOV	EAX,LAST_SEG_OS2_NUMBER

		CONV_EAX_SEGTBL_ECX

		MOV	[ECX]._SEGTBL_PSIZE,EDX

		RET

RETTT:
		XOR	EDX,EDX
		JMP	FINI_DONE1

USE_OLD:
		;
		;PROCESS STORED STUFF IN RESIDENT STRUCTURE TO FINAL
		;
		PUSH	EBP
		MOV	EBX,OFF RESIDENT_STRUCTURE._SEQ_TABLE

		XOR	ESI,ESI
		;
		;THERE ARE NEW_REPT_ADDR BYTES TO PROCESS
		;
USE_OLD_5:
		CALL	GET_COMMAND
		JC	FIN_DONE

		CALL	MOVE_DATA
		JMP	USE_OLD_5

FIN_DONE:
		POP	EBP
		JMP	FINI_DONE

PEXEPACK_FINISH	ENDP


GET_COMMAND	PROC	NEAR
		;
		;
		;
		SUB	NEW_REPT_ADDR,4
		JC	L9$

		CMP	ESI,PAGE_SIZE-4
		JA	L5$

		CALL	CONVERT_SUBBX_TO_EAX

		MOV	EBP,EAX
		MOV	EAX,[EAX+ESI]

		MOV	ECX,EAX
		ADD	ESI,4

		SHR	ECX,16			;ITEM SIZE
		AND	EAX,0FFFFH		;COUNT

		RET

L5$:
		MOV	EDI,OFF TEMP_RECORD1
		MOV	ECX,4
L6$:
		PUSH	ECX
		CALL	GET_BYTE

		POP	ECX
		MOV	[EDI],AL

		INC	EDI
		DEC	ECX

		JNZ	L6$

		MOV	EAX,TEMP_RECORD1

		MOV	ECX,EAX

		SHR	ECX,16
		AND	EAX,0FFFFH

		RET

L9$:
		XOR	ECX,ECX
		MOV	EAX,[EBX]

		TEST	EAX,EAX
		JZ	L99$

		MOV	[EBX],ECX
		CALL	RELEASE_BLOCK
L99$:
		STC

		RET

GET_COMMAND	ENDP


MOVE_DATA	PROC	NEAR
		;
		;EAX IS REPEAT COUNT
		;ECX IS ITEM SIZE (2, OR 4, OR XXXX)
		;
		DEC	EAX
		JNZ	L5$
		;
		;JUST MOVE CX BYTES...
		;
L1$:
		;
		;MOVE SMALLER OF ECX AND PAGE_SIZE-ESI
		;
		MOV	EAX,PAGE_SIZE

		SUB	EAX,ESI

		CMP	EAX,ECX
		JB	L2$

		MOV	EAX,ECX
L2$:
		PUSHM	EAX,ECX

		MOV	ECX,EAX
		CALL	CONVERT_SUBBX_TO_EAX

		ADD	EAX,ESI
		CALL	MOVE_EAX_TO_FINAL_HIGH_WATER

		POPM	ECX,EAX

		SUB	NEW_REPT_ADDR,EAX
		ADD	ESI,EAX

		CMP	ESI,PAGE_SIZE
		JNZ	L3$

		PUSH	EAX
		XOR	EDX,EDX

		MOV	EAX,[EBX]
		MOV	[EBX],EDX

		ADD	EBX,4
		CALL	RELEASE_BLOCK

		POP	EAX
		XOR	ESI,ESI
L3$:
		SUB	ECX,EAX
		JNZ	L1$
L9$:
		RET

L5$:
		;
		;EAX IS REPEAT COUNT
		;ECX IS ITEM SIZE (2 OR 4)
		;
		INC	EAX
		MOV	EDI,OFF TEMP_RECORD1
		;
		;MOVING WORDS OR DWORDS...
		;
		PUSH	EAX
		MOV	EDX,ECX

		PUSH	EDX
L55$:
		PUSH	ECX
		CALL	GET_BYTE

		POP	ECX
		MOV	[EDI],AL

		INC	EDI
		DEC	ECX

		JNZ	L55$

		POPM	ECX,EDX

		SUB	NEW_REPT_ADDR,ECX
L6$:
		;
		;EDX IS # OF TIMES TO REPEAT
		;ECX IS SIZE OF ITEM
		;
		PUSHM	EDX,ECX

		MOV	EAX,OFF TEMP_RECORD1
		CALL	MOVE_EAX_TO_FINAL_HIGH_WATER

		POPM	ECX,EDX

		DEC	EDX
		JNZ	L6$

		RET

MOVE_DATA	ENDP


GET_BYTE	PROC	NEAR
		;
		;GET BYTE FROM BX:SI IN AL
		;
		CMP	ESI,PAGE_SIZE
		JZ	L5$
L1$:
		CALL	CONVERT_SUBBX_TO_EAX

		MOV	EBP,EAX
		MOV	AL,[EAX+ESI]

		INC	ESI

		CMP	ESI,PAGE_SIZE
		JZ	L4$

		RET

L4$:
		PUSH	EAX
		XOR	ECX,ECX

		MOV	EAX,[EBX]
		MOV	[EBX],ECX

		ADD	EBX,4
		CALL	RELEASE_BLOCK

		POP	EAX
		XOR	ESI,ESI

		RET

L5$:
		CALL	L4$

		JMP	L1$

GET_BYTE	ENDP


OS2_EXEPACK_FLUSH	PROC
		;
		;
		;
		JMP	REAL_EXEPACK_FLUSH

OS2_EXEPACK_FLUSH	ENDP


PMOVE_DX_TARG	PROC	NEAR
		;
		;MOVE DX BYTES FROM DS:SI-DX TO TARG_ADDR, UPDATE TARG_ADDR
		;AND PACK_SO_FAR
		;
		ADD	PACK_SO_FAR,EDX
		JZ	L9$
PMOVE_DX_TARG_A::
		MOV	EAX,ESI
		MOV	ECX,EDX

		SUB	EAX,EDX
		MOV	EDX,TARG_ADDR

		TEST	ECX,ECX
		JZ	L8$

		ADD	TARG_ADDR,ECX
		CALL	PMOVE_LDATA_2
L8$:
		XOR	EDX,EDX
L9$:
		RET

PMOVE_DX_TARG	ENDP


PFLUSH_GET_NEXT_BUFFER	PROC
		;
		;
		;
		CALL	PMOVE_DX_TARG
		;
		JMP	GET_NEXT_BUFFER

PFLUSH_GET_NEXT_BUFFER	ENDP


FD_SKIP:
FW_SKIP:
FB_SKIP:
		RET


PSTORE_DWORDTYPE:
		ADD	PACK_SO_FAR,EDX
		JZ	FD_SKIP
		;
		;OK, IF BYTES GENERATED, PROVE IT
		;
		MOV	EDX,4
		CALL	PMOVE_DX_TARG_A

		MOV	EDX,4
		JMP	PSTORE_PACK_DX

PSTORE_WORDTYPE:
		ADD	PACK_SO_FAR,EDX
		JZ	FW_SKIP

		MOV	EDX,2
		CALL	PMOVE_DX_TARG_A

		MOV	EDX,2
		JMP	PSTORE_PACK_DX

PSTORE_BYTETYPE:
		;
		;BX DUPLICATE BYTES LIKE AL HAVE BEEN STORED
		;
		ADD	PACK_SO_FAR,EDX
		JZ	FB_SKIP

		MOV	EDX,1
		CALL	PMOVE_DX_TARG_A

		MOV	EDX,1
PSTORE_PACK_DX:
		PUSH	ESI
		MOV	ESI,OFF PACK_SO_FAR

		MOV	WPTR PACK_SO_FAR+2,DX
		JMP	PSBDX_1

PSTORE_BYTES_DX_1	PROC	NEAR
		;
		;
		;
		CMP	EDX,11
		JA	L5$

		CMP	PACK_SO_FAR,0
		JNZ	L5$

		CMP	EDX,2
		JB	L5$
		;
		;MAYBE WE CAN SQUEEZE JUST A LITTLE BIT MORE...
		;
		;FIRST, TRY FOR DX MATCHING BYTES...
		;
		SUB	ESI,EDX
		MOV	ECX,EDX

		MOV	EDI,ESI
		MOV	AL,[ESI]

		REPE	SCASB

		JZ	L1$		;YES!

		MOV	EDI,ESI
		MOV	ECX,EDX

		SHR	ECX,1
		JC	L4$		;CANNOT!

		MOV	EAX,[ESI]

		REPE	SCASW

		JNZ	L4$		;NOPE!
		;
		;WORDS
		;
		ADD	ESI,EDX

		SHR	EDX,1
		JMP	PSTORE_WORDTYPE

L1$:
		;
		;BYTES
		;
		ADD	ESI,EDX
		JMP	PSTORE_BYTETYPE

L4$:
		ADD	ESI,EDX
L5$:
		CALL	PMOVE_DX_TARG

		MOV	EAX,PACK_SO_FAR

		TEST	EAX,EAX
		JZ	L9$

		PUSH	ESI
		MOV	ESI,OFF PACK_REPT_COUNT+2

		MOV	WPTR [ESI],1
PSBDX_1::
		MOV	EDX,NEW_REPT_ADDR
		MOV	ECX,4

		MOV	EAX,ESI
		CALL	PMOVE_LDATA_2

		POP	ESI
		MOV	ECX,TARG_ADDR

		MOV	NEW_REPT_ADDR,ECX
		XOR	EAX,EAX

		ADD	ECX,4
		MOV	PACK_SO_FAR,EAX

		MOV	TARG_ADDR,ECX
L9$:
		RET

PSTORE_BYTES_DX_1	ENDP


PMOVE_LDATA_2	PROC	NEAR
		;
		;
		;
		BITT	EXEPACK_USING_NEW
		JNZ	MOVE_EAX_TO_EDX_FINAL

		PUSH	EBX
		MOV	EBX,EDX

		MOV	EDX,OFF RESIDENT_STRUCTURE
		CALL	STORE_EAXECX_EDXEBX_RANDOM

		POP	EBX

		RET

PMOVE_LDATA_2	ENDP


FLUSH_RESIDENT	PROC	NEAR
		;
		;FLUSH DATA FROM RESIDENT_STRUCTURE TO FINAL, WE ARE KEEPING
		;IT, UPDATE POINTERS, ETC
		;
		SETT	EXEPACK_USING_NEW

		PUSHM	EDI,ESI,EBX
		MOV	ESI,OFF RESIDENT_STRUCTURE._SEQ_TABLE

		MOV	EDI,OFF EXETABLE
		MOV	ECX,32K/PAGE_SIZE*2 +1	;64K + 1 BLOCK

		REP	MOVSD

		MOV	EDI,OFF RESIDENT_STRUCTURE._SEQ_TABLE
		XOR	EAX,EAX

		MOV	CL,32K/PAGE_SIZE*2 +1	;64K + 1 BLOCK

		REP	STOSD
		;
		;HOW MANY TO MOVE?
		;
		;HMMM, MOVE FROM ZERO TO NEW_REPT_ADDR, THEN
		;	FROM NEW_REPT_ADDR+4 TO TARG_ADDR
		;
		MOV	EAX,TARG_ADDR
		MOV	ECX,NEW_REPT_ADDR

		SUB	EAX,ECX

		CMP	EAX,4
		JZ	L5$		;SIMPLEST CASE..
		;
		;OK, MOVE ZERO TO NEW_REPT_ADDR
		;
		TEST	ECX,ECX
		JZ	L3$

		XOR	EAX,EAX
		CALL	MOVE_HELPER
L3$:
		;
		;MOVE FROM NEW_REPT_ADDR+4 TO TARG_ADDR
		;
		MOV	EAX,NEW_REPT_ADDR
		MOV	ECX,TARG_ADDR

		ADD	EAX,4

		SUB	ECX,EAX
		JZ	L9$

		CALL	MOVE_HELPER

		JMP	L9$

L5$:
		MOV	EAX,NEW_REPT_ADDR
		CALL	FLUSH_EAX_TO_FINAL
L9$:
		CALL	RELEASE_EXETABLE_5

		MOV	EAX,EXEPACK_SEGMENT_START

		ADD	NEW_REPT_ADDR,EAX

		ADD	TARG_ADDR,EAX
		;
		;MARK SEGMENT ITERATED
		;
		MOV	EAX,LAST_SEG_OS2_NUMBER

		CONV_EAX_SEGTBL_ECX

		POPM	EBX,ESI,EDI
		OR	[ECX]._SEGTBL_FLAGS,MASK SR_ITERATE

		RET

FLUSH_RESIDENT	ENDP


MOVE_HELPER	PROC	NEAR
		;
		;MOVE ECX BYTES FROM EXETABLE[EAX] TO EXEPACK_SEGMENT_START[EAX]
		;
		TEST	ECX,ECX
		JZ	L9$

		PUSHM	ESI,EBX

		MOV	EBX,EAX
		MOV	ESI,EAX

		SHR	EBX,PAGE_BITS
		MOV	EDX,EXEPACK_SEGMENT_START

		ADD	EDX,ESI
		AND	ESI,PAGE_SIZE-1

		LEA	EBX,EXETABLE[EBX*4]
L1$:
		;
		;NOW MOVE SMALLER OF PAGE_SIZE-SI AND CX
		;
		MOV	EAX,PAGE_SIZE

		SUB	EAX,ESI

		CMP	EAX,ECX
		JB	L2$

		MOV	EAX,ECX
L2$:
		PUSHM	EDX,ECX,EAX
		MOV	ECX,EAX

		CALL	CONVERT_SUBBX_TO_EAX

		ADD	EAX,ESI
		CALL	MOVE_EAX_TO_EDX_FINAL

		POPM	EAX,ECX,EDX
		ADD	ESI,EAX

		CMP	ESI,PAGE_SIZE
		JNZ	L3$

		PUSHM	ECX,EAX

		XOR	ECX,ECX
		MOV	EAX,[EBX]

		MOV	[EBX],ECX
		CALL	RELEASE_BLOCK

		POPM	EAX,ECX
L3$:
		ADD	EBX,4
		XOR	ESI,ESI

		ADD	EDX,EAX

		SUB	ECX,EAX
		JNZ	L1$

		POPM	EBX,ESI
L9$:
		RET

MOVE_HELPER	ENDP


		.DATA?

TEMP_RECORD1	DD	?


		END

